package org.basis.algorithm.summary;

import com.google.common.collect.Sets;
import org.apache.commons.collections4.CollectionUtils;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

/**
 * 集合求交集测试
 *
 * @author Mr_wenpan@163.com 2022/01/13 11:33
 */
public class IntersectionTest {

    public static void main(String[] args) {
        HashSet<String> set1 = new HashSet<>();
        HashSet<String> set2 = new HashSet<>();
        set1.add("w");
        set1.add("e");
        set1.add("x");
        set2.add("p");
        set2.add("a");
        set2.add("n");
        set1.retainAll(set2);
        System.out.println("set1 = " + set1);
        System.out.println("set1 = " + set2);
    }

    /**
     * 使用guava提供的Sets来求两个集合的交集
     *
     * @return 返回交集元素集合
     */
    public static HashSet<String> guavaIntersection(List<String> list1, List<String> list2) {
        // 任意一个为空都返回交集个数为0
        if (CollectionUtils.isEmpty(list1) || CollectionUtils.isEmpty(list2)) {
            return null;
        }
        long start = System.nanoTime();
        Sets.SetView<String> intersection = Sets.intersection(new HashSet<>(list1), new HashSet<>(list2));
        System.out.println("通过guava的Sets来求交集耗时：" + (System.nanoTime() - start));
        // 将交集结果写入到set里
        HashSet<String> res = new HashSet<>();
        intersection.copyInto(res);
        return res;
    }

    /**
     * 通过retainAll来求两个集合的交集
     * 特别注意：list1.retainAll(list2) 如果有交集，那么list集合里便会只剩交集元素了，list2不变，如果没有交集，则list1会被清空，list2不变
     */
    public static void retailAllIntersection(List<String> list1, List<String> list2) {
        // 任意一个为空都返回交集个数为0
        if (CollectionUtils.isEmpty(list1) || CollectionUtils.isEmpty(list2)) {
            return;
        }
        long start = System.nanoTime();
        list1.retainAll(list2);
        System.out.println("通过JDK的retainAll来求交集耗时：" + (System.nanoTime() - start));
    }

    /**
     * 通过hashset来求两个集合的交集
     *
     * @return 返回交集元素，但并不改变list1和list2的集合元素
     */
    public static List<String> intersectionByHashSet(List<String> list1, List<String> list2) {
        // 任意一个为空都返回交集个数为0
        if (CollectionUtils.isEmpty(list1) || CollectionUtils.isEmpty(list2)) {
            return null;
        }
        HashSet<String> set = new HashSet<>(list1);
        List<String> intersection = new ArrayList<>();
        for (String str : list2) {
            if (set.contains(str)) {
                intersection.add(str);
            }
        }
        return intersection;
    }

    /**
     * 通过位图来求交集，
     * 注意：位图只能求数字类型的交集
     */
    public static List<Integer> intersectionByBitMap(List<Integer> list1, List<Integer> list2) {

        return null;
    }
}
